using System;
using System.Data;
using System.Collections;
using System.Xml;
using System.Xml.Serialization;
using System.Reflection;
using BEGDC.CC.Entity;


using Nullables;

namespace CCEmailService
{
	/// <summary>
	/// Summary description for EmailByTemplateBySMTP.
	/// </summary>
	public class EmailTemplateResolver
	{
		private const String LEFT_MARKER = "${";
		private const String RIGHT_MARKER = "}";	
		private const string projectRole = "ApplicationRole";
		private const string role = "Role";
		private const string owner = "Owner";
		private const string current = "Current";

		public static string ResolveEmailTemplate(string text, object obj)
		{
			
			int leftMarkerIndex = text.IndexOf(LEFT_MARKER);
			int rightMarkerIndex = text.IndexOf(RIGHT_MARKER, leftMarkerIndex + LEFT_MARKER.Length);

			while ((leftMarkerIndex != - 1) && (rightMarkerIndex != - 1))
			{
				string attributeName = text.Substring(leftMarkerIndex + LEFT_MARKER.Length, (rightMarkerIndex) - (leftMarkerIndex + LEFT_MARKER.Length)).Trim();
				try
				{
					string attributeString = string.Empty; //ProjectTQ.PlanAQEndTime
					char[] spearates = {'.'};
					string[] attributes = attributeName.Split(spearates);

					object tempobj = obj;
					for(int i=0; i<attributes.Length; i++)
					{
						if (tempobj == null)
							break;
						string att_name = attributes[i];
						Type t = tempobj.GetType();
						Type inter = typeof(Nullables.INullableType);
						if (inter.IsInstanceOfType(tempobj))
						{
							Nullables.INullableType inobj = (Nullables.INullableType)tempobj;
							if (inobj.HasValue)
								tempobj = inobj.Value;
							else
								tempobj = null;
							break;
						}
						
						PropertyInfo[] properties =t.GetProperties();
						bool is_find = false;
						foreach(PropertyInfo attribute in properties)
						{
							if (attribute.Name.ToLower() == att_name.ToLower())
							{
								tempobj = attribute.GetValue(tempobj, null);
                                //omit -B
                                if (att_name == "AppNo"){
                                    if (tempobj.ToString().StartsWith("CR") || tempobj.ToString().StartsWith("IBG"))
                                    {
                                        if (tempobj.ToString().EndsWith("-B"))
                                            tempobj = tempobj.ToString().Substring(0, tempobj.ToString().Length - 2);
                                    } 
                                }

								is_find = true;
								break;
							}
						}
						if (!is_find)
							throw new Exception("Template Error");
					}

					if (tempobj != null)
						attributeString = tempobj.ToString();
					
					text = text.Substring(0, leftMarkerIndex) + attributeString + text.Substring(rightMarkerIndex + RIGHT_MARKER.Length);
					rightMarkerIndex = rightMarkerIndex + attributeString.Length - attributeName.Length - LEFT_MARKER.Length - RIGHT_MARKER.Length;
				}
				catch (Exception e)
				{
					throw new Exception(e.Message);						
				}

				leftMarkerIndex = text.IndexOf(LEFT_MARKER, rightMarkerIndex + RIGHT_MARKER.Length);
				rightMarkerIndex = text.IndexOf(RIGHT_MARKER, leftMarkerIndex + LEFT_MARKER.Length);
			}
			text = text.Replace("{and}", "&");
			return text;
		}

		public static string ResolverReceiver(string receiver, object project)
		{
			string nameEN = string.Empty;
			string nameCN = string.Empty;
			return ResolverReceiver(receiver, project, out nameEN, out nameCN);
		}

		public static string ResolverReceiver(string receiver, object project, out string nameEN, out string nameCN)
		{
			nameCN = string.Empty;
			nameEN = string.Empty;

			string[] emails = receiver.Split( new char[]{';'});
			string email = string.Empty;
			
			for(int i=0; i<emails.Length; i++)
			{
				if (i > 0)
					email += ";";
				string nameENTemp = string.Empty;
				string nameCNTemp = string.Empty;
				email += ResolverOneReceiver(emails[i], project,out nameENTemp,out nameCNTemp);

				nameCN += nameCNTemp + ",";
				nameEN += nameENTemp + ",";
				
			}
			nameCN = nameCN.TrimEnd(',');
			nameEN = nameEN.TrimEnd(',');
			return email;

		}

		public static string ResolverOneReceiver(string receiver, object application, out string nameEN, out string nameCN)
		{
			int index = -1;
			string roleName = string.Empty;
			string email = string.Empty;
			nameEN = string.Empty;
			nameCN = string.Empty;

			BEGDC.CC.BL.Common.IUtility iutility = BEGDC.Utility.Castle.AppContainer.Instance[BEGDC.CC.BL.Common.ServiceConst.UtilityService] as  BEGDC.CC.BL.Common.IUtility;
			BEGDC.CC.BL.UserManagement.IUser userService = BEGDC.Utility.Castle.AppContainer.Instance[BEGDC.CC.BL.Common.ServiceConst.UserService] as BEGDC.CC.BL.UserManagement.IUser;

			//==================receiver belongs to a project=========================
			index = receiver.IndexOf( projectRole );
			if( index > -1 )
			{
				roleName = receiver.Substring( index + projectRole.Length + 1, receiver.Length - projectRole.Length - 2 );
				
				IList list = iutility.GetMember(((BEGDC.CC.Entity.Application)application).Id, roleName );
				if( list.Count == 0 )
					return string.Empty;
				else
				{
					BEGDC.CC.Entity.FlowMember member = list[0] as BEGDC.CC.Entity.FlowMember;
					if(member.Employee != null)
					{
						email = member.Employee.Email;
						nameEN = member.Employee.NameCN;
						nameCN = member.Employee.NameChinese;
					}
					else
					{
						DataTable table = userService.GetEmailByRole( roleName );

						foreach( DataRow row in table.Rows )
						{
							if( email + string.Empty != string.Empty )
								email += ";";
							email += row["Email"].ToString();

						}		
						nameEN = roleName;
						nameCN = roleName;
					}
				}
			}
			else
			{
				//======================Receiver belongs to role group===================
				index = receiver.IndexOf( role );
				if( index > -1 )
				{
					roleName = receiver.Substring( index + role.Length + 1, receiver.Length - role.Length - 2 );
					DataTable table = userService.GetEmailByRole( roleName );

					foreach( DataRow row in table.Rows )
					{
						if( email + string.Empty != string.Empty )
							email += ";";
						email += row["Email"].ToString();

					}
					nameEN = roleName;
					nameCN = roleName;

				}
				else
				{
					index = receiver.IndexOf( owner );
					if( index > -1 )
					{
						string owneremail = ((BEGDC.CC.Entity.Application)application).RequesterNo.Email;
						if( email + string.Empty != string.Empty )
							email += ";";
						email += owneremail;

						nameEN = ((BEGDC.CC.Entity.Application)application).RequesterNo.NameEN;
						nameCN = ((BEGDC.CC.Entity.Application)application).RequesterNo.NameCN;

						//						BEGDC.CC.BL.UserManagement.IUser userService = BEGDC.Utility.Castle.AppContainer.Instance[BEGDC.CC.BL.Common.ServiceConst.UserService] as BEGDC.CC.BL.UserManagement.IUser;
						//						DataTable table = userService.GetProjectOwnerEmail(((BEGDC.CC.Entity.Application)application).Id);
						//
						//						foreach( DataRow row in table.Rows )
						//						{
						//							if( email + string.Empty != string.Empty )
						//								email += ";";
						//							email += row["Email"].ToString();
						//						}
					}
					else 
					{
						index = receiver.IndexOf( current );
						if (index > -1)
						{
							BEGDC.CC.Entity.Application app = (BEGDC.CC.Entity.Application)application;
							string empNo = ((BEGDC.CC.Entity.FlowInstance)app.FlowInstances[0]).CurrentActiveOwner;

							BEGDC.CC.Entity.Employee emp = userService.GetUserByID(empNo);
							if (emp != null)
							{
								email = emp.Email;
								nameEN = emp.NameEN;
								nameCN = emp.NameCN;
							}
						}
						else
						{
							email = ResolveEmailTemplate(receiver, application);
							nameEN = receiver;
							nameCN = receiver;
						}
					}
				}
			}
			
			return email;
		}
	
	}
}
